Iteration of DESEQ2 over: Region level, then treatment comparison

Region level - e.g. Tissue region, indicates all DE data from same tissue and experiment. These are analysed independently from every other region.

Within a region, the treatments are compared.

However, for downstream plotting, the normalised data from all regions is calculated. Particularly important for co-expression related analysis.

To normalise gene expression across all tissues, the ’DESEQ2 - all tissues - FULL - **’ needs to be used.

#Step 1a in pipeline

1. Import metadata


#import data about columns, that is each column should be metadata about the sample/animal. Particularly include all treatment info and animal ID in columns. 
coldata <-  data.table::fread(file = "../Sheep_RNAseq/Inputs/coldata_new_names_20201105.csv") %>% 
  dplyr::mutate(sample_names = paste0(Region, "_", ID, "__", Diet))


#import data about columns, that is each column should be metadata about the sample/animal. Particularly include all treatment info and animal ID in columns. 
coldata <-  data.table::fread(file = "../Sheep_RNAseq/Inputs/coldata_new_names_20201105.csv") %>% 
  dplyr::mutate(sample_names = paste0(Region, "_", ID, "__", Diet))

2. import all count tables and join

TODO - make it handle when too many names are in coldata compared to cts_all Error: Can’t subset columns that don’t exist. x Columns BONE_8__Feed, BONE_20__Fast, and BONE_15__Refeed don’t exist.

#re-run check
cts_filtered <- check_count_matrix(count_data = cts_all, 
                            colData = coldata,
                            column_with_col_names = sample_names
                            )
PASS: All columns in count_data have matching data in colData
PASS: Rownames not detected
PASS: First column name is 'gene_ensembl'

 Dimensions of raw counts dataset BEFORE sorting:
genes:  27054     samples:  239

 Number of samples in colData: 239

 Dimensions of raw counts dataset AFTER sorting:
genes:  27054     samples:  239

3. convert ensemble ID to gene ID


test_annot <- annotate_gene_ensembl(cts_filtered, organism = "oaries")
Using organism: oaries
Important - this produces duplicate gene names from annotation - however gene_ensembl remain unique.
      This is why it's important to use gene_ensembl for all tasks and annotate output at end.
[1] "duplicate genes in annotation:  1801"

Prepare data

TO DO: make a wrapper for this with specific checks of data / auto matrix

#subset columns to be every third, to make testing quicker
test_data <- test_data[,seq(0,ncol(cts_filtered)-1,4)] 
Error: subscript contains out-of-bounds indices

#4. Generate DE results TO DO: - detect all options for ‘top_level_filter’ and parse to map().

DE_out <- 
  purrr::map(list("LIV"),
             auto_generate_DE_results, 
             se_data = test_data,
             top_level_name = Region,
             column_of_samples = sample_names,
             samples_to_remove = NA,
             DESeq2_formula_design = ~Region_Diet,
             rowSums_filter = 10, #for dds filtering
             results_contrast_factor = Region_Diet,
             results_combinations = NA,
             use_IHW_filtering = TRUE,
             alpha = 0.05,
             gene_annotations = test_annot,
             export_tables = TRUE,
             export_dir = "./outputs/normalised_counts3/")


 ******************* Start of -  LIV ******************* 


renaming the first element in assays to 'counts'
Warning in DESeq2::DESeqDataSet(se_data0, design = DESeq2_formula_design) :
  some variables in design formula are characters, converting to factors
Beginning DESeq analysis...
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
Completed DESeq analysis.
Plotting cooks distance...
Cooks distance plot complete.
Generating pairwise DESeq2 results...
[1] "Contrast levels: LIV_HCP.HP.UMEI, LIV_LCP.HP.UMEI, LIV_LCP.LP.UMEI, LIV_HCP.HP.RMEI, LIV_HCP.LP.UMEI"


 log2 fold change (MLE): Region_Diet LIV_HCP.HP.UMEI vs LIV_LCP.HP.UMEI

out of 16278 with nonzero total read count
adjusted p-value < 0.05
LFC > 0 (up)       : 82, 0.5%
LFC < 0 (down)     : 36, 0.22%
outliers [1]       : 8, 0.049%
[1] see 'cooksCutoff' argument of ?results
see metadata(res)$ihwResult on hypothesis weighting


 log2 fold change (MLE): Region_Diet LIV_HCP.HP.UMEI vs LIV_LCP.LP.UMEI

out of 16278 with nonzero total read count
adjusted p-value < 0.05
LFC > 0 (up)       : 47, 0.29%
LFC < 0 (down)     : 37, 0.23%
outliers [1]       : 8, 0.049%
[1] see 'cooksCutoff' argument of ?results
see metadata(res)$ihwResult on hypothesis weighting


 log2 fold change (MLE): Region_Diet LIV_HCP.HP.UMEI vs LIV_HCP.HP.RMEI

out of 16278 with nonzero total read count
adjusted p-value < 0.05
LFC > 0 (up)       : 236, 1.4%
LFC < 0 (down)     : 197, 1.2%
outliers [1]       : 8, 0.049%
[1] see 'cooksCutoff' argument of ?results
see metadata(res)$ihwResult on hypothesis weighting


 log2 fold change (MLE): Region_Diet LIV_HCP.HP.UMEI vs LIV_HCP.LP.UMEI

out of 16278 with nonzero total read count
adjusted p-value < 0.05
LFC > 0 (up)       : 41, 0.25%
LFC < 0 (down)     : 21, 0.13%
outliers [1]       : 8, 0.049%
[1] see 'cooksCutoff' argument of ?results
see metadata(res)$ihwResult on hypothesis weighting


 log2 fold change (MLE): Region_Diet LIV_LCP.HP.UMEI vs LIV_LCP.LP.UMEI

out of 16278 with nonzero total read count
adjusted p-value < 0.05
LFC > 0 (up)       : 2, 0.012%
LFC < 0 (down)     : 11, 0.068%
outliers [1]       : 8, 0.049%
[1] see 'cooksCutoff' argument of ?results
see metadata(res)$ihwResult on hypothesis weighting


 log2 fold change (MLE): Region_Diet LIV_LCP.HP.UMEI vs LIV_HCP.HP.RMEI

out of 16278 with nonzero total read count
adjusted p-value < 0.05
LFC > 0 (up)       : 7, 0.043%
LFC < 0 (down)     : 13, 0.08%
outliers [1]       : 8, 0.049%
[1] see 'cooksCutoff' argument of ?results
see metadata(res)$ihwResult on hypothesis weighting


 log2 fold change (MLE): Region_Diet LIV_LCP.HP.UMEI vs LIV_HCP.LP.UMEI

out of 16278 with nonzero total read count
adjusted p-value < 0.05
LFC > 0 (up)       : 2, 0.012%
LFC < 0 (down)     : 1, 0.0061%
outliers [1]       : 8, 0.049%
[1] see 'cooksCutoff' argument of ?results
see metadata(res)$ihwResult on hypothesis weighting


 log2 fold change (MLE): Region_Diet LIV_LCP.LP.UMEI vs LIV_HCP.HP.RMEI

out of 16278 with nonzero total read count
adjusted p-value < 0.05
LFC > 0 (up)       : 5, 0.031%
LFC < 0 (down)     : 14, 0.086%
outliers [1]       : 8, 0.049%
[1] see 'cooksCutoff' argument of ?results
see metadata(res)$ihwResult on hypothesis weighting


 log2 fold change (MLE): Region_Diet LIV_LCP.LP.UMEI vs LIV_HCP.LP.UMEI

out of 16278 with nonzero total read count
adjusted p-value < 0.05
LFC > 0 (up)       : 6, 0.037%
LFC < 0 (down)     : 1, 0.0061%
outliers [1]       : 8, 0.049%
[1] see 'cooksCutoff' argument of ?results
see metadata(res)$ihwResult on hypothesis weighting


 log2 fold change (MLE): Region_Diet LIV_HCP.HP.RMEI vs LIV_HCP.LP.UMEI

out of 16278 with nonzero total read count
adjusted p-value < 0.05
LFC > 0 (up)       : 8, 0.049%
LFC < 0 (down)     : 5, 0.031%
outliers [1]       : 8, 0.049%
[1] see 'cooksCutoff' argument of ?results
see metadata(res)$ihwResult on hypothesis weighting
Results generated.
Plotting MA plots (default DESeq2 style for QC)...

Finished MA plots.
Plotting p value histograms (for QC)...

Finished plotting p value histograms.
./outputs/normalised_counts/ Directory exists
Normalised tables exported to the sub-directory: ./outputs/normalised_counts/
Preparing data for output...
List output succesfully generated. Contains: dds_wald_object [dds after call to DESeq()], list of DESeq result objects and list of pairwise plots.


 ******************* END of -  LIV ******************* 

#5. Accessing results TO DO:

Accessing sorted DE Tables - pre-PIF

DE_out_test$LIV_DESeq2_Output$DESeq2_annot_df
$`LIV_HCP.HP.UMEI vs LIV_LCP.HP.UMEI`

$`LIV_HCP.HP.UMEI vs LIV_LCP.LP.UMEI`

$`LIV_HCP.HP.UMEI vs LIV_HCP.HP.RMEI`

$`LIV_HCP.HP.UMEI vs LIV_HCP.LP.UMEI`

$`LIV_LCP.HP.UMEI vs LIV_LCP.LP.UMEI`

$`LIV_LCP.HP.UMEI vs LIV_HCP.HP.RMEI`

$`LIV_LCP.HP.UMEI vs LIV_HCP.LP.UMEI`

$`LIV_LCP.LP.UMEI vs LIV_HCP.HP.RMEI`

$`LIV_LCP.LP.UMEI vs LIV_HCP.LP.UMEI`

$`LIV_HCP.HP.RMEI vs LIV_HCP.LP.UMEI`
NA

#Workign

#testing how many have real names
 x %>% 
        as.data.frame() %>% 
        tibble::rownames_to_column(var = "gene_ensembl") %>%
        dplyr::left_join(annot, by = c("gene_ensembl")) %>%
        dplyr::select(.data$gene_ensembl,
                      .data$gene_name,
                      .data$description,
                      tidyselect::everything()) %>% 
        arrange(.data$padj)

Code for renaming old cts tables

LS0tCnRpdGxlOiAiVGVzdGluZyBERVNFUTIiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCkl0ZXJhdGlvbiBvZiBERVNFUTIgb3ZlcjogUmVnaW9uIGxldmVsLCB0aGVuIHRyZWF0bWVudCBjb21wYXJpc29uCgpSZWdpb24gbGV2ZWwgLSBlLmcuIFRpc3N1ZSByZWdpb24sIGluZGljYXRlcyBhbGwgREUgZGF0YSBmcm9tIHNhbWUgdGlzc3VlIGFuZCBleHBlcmltZW50LiBUaGVzZSBhcmUgYW5hbHlzZWQgaW5kZXBlbmRlbnRseSBmcm9tIGV2ZXJ5IG90aGVyIHJlZ2lvbi4KCldpdGhpbiBhIHJlZ2lvbiwgdGhlIHRyZWF0bWVudHMgYXJlIGNvbXBhcmVkLgoKCkhvd2V2ZXIsIGZvciBkb3duc3RyZWFtIHBsb3R0aW5nLCB0aGUgbm9ybWFsaXNlZCBkYXRhIGZyb20gYWxsIHJlZ2lvbnMgaXMgY2FsY3VsYXRlZC4gUGFydGljdWxhcmx5IGltcG9ydGFudCBmb3IgY28tZXhwcmVzc2lvbiByZWxhdGVkIGFuYWx5c2lzLgoKClRvIG5vcm1hbGlzZSBnZW5lIGV4cHJlc3Npb24gYWNyb3NzIGFsbCB0aXNzdWVzLCB0aGUgJ0RFU0VRMiAtIGFsbCB0aXNzdWVzIC0gRlVMTCAtICoqJyBuZWVkcyB0byBiZSB1c2VkLgoKI1N0ZXAgMWEgaW4gcGlwZWxpbmUKCiMgMS4gSW1wb3J0IG1ldGFkYXRhCmBgYHtyfQoKI2ltcG9ydCBkYXRhIGFib3V0IGNvbHVtbnMsIHRoYXQgaXMgZWFjaCBjb2x1bW4gc2hvdWxkIGJlIG1ldGFkYXRhIGFib3V0IHRoZSBzYW1wbGUvYW5pbWFsLiBQYXJ0aWN1bGFybHkgaW5jbHVkZSBhbGwgdHJlYXRtZW50IGluZm8gYW5kIGFuaW1hbCBJRCBpbiBjb2x1bW5zLiAKY29sZGF0YSA8LSAgZGF0YS50YWJsZTo6ZnJlYWQoZmlsZSA9ICIuLi9TaGVlcF9STkFzZXEvSW5wdXRzL2NvbGRhdGFfbmV3X25hbWVzXzIwMjAxMTA1LmNzdiIpICU+JSAKICBkcGx5cjo6bXV0YXRlKHNhbXBsZV9uYW1lcyA9IHBhc3RlMChSZWdpb24sICJfIiwgSUQsICJfXyIsIERpZXQpKQoKY29sZGF0YSA8LSAgZGF0YS50YWJsZTo6ZnJlYWQoZmlsZSA9ICIuL2NvbGRhdGFfdGVzdC5jc3YiKSAlPiUgCiAgZHBseXI6Om11dGF0ZShzYW1wbGVfbmFtZXMgPSBwYXN0ZTAoUmVnaW9uLCAiXyIsIElELCAiX18iLCBEaWV0KSkKCgpgYGAKCgoKCiMgMi4gaW1wb3J0IGFsbCBjb3VudCB0YWJsZXMgYW5kIGpvaW4KVE9ETyAtIG1ha2UgaXQgaGFuZGxlIHdoZW4gdG9vIG1hbnkgbmFtZXMgYXJlIGluIGNvbGRhdGEgY29tcGFyZWQgdG8gY3RzX2FsbApFcnJvcjogQ2FuJ3Qgc3Vic2V0IGNvbHVtbnMgdGhhdCBkb24ndCBleGlzdC4KeCBDb2x1bW5zIGBCT05FXzhfX0ZlZWRgLCBgQk9ORV8yMF9fRmFzdGAsIGFuZCBgQk9ORV8xNV9fUmVmZWVkYCBkb24ndCBleGlzdC4KYGBge3IgbWF0cml4X2lucHV0LCBlY2hvPVR9CgoKY3RzX2FsbCA8LSBkYXRhLnRhYmxlOjpmcmVhZChmaWxlPSAiLi9jdHNfcmVuYW1lZF9hbGxfU2hlZXAudHh0IikKCiMjIyMjIyAqKioqKioqKioqKioKIyBVc2UgbmV3IGZ1bmN0aW9uCmN0c19maWx0ZXJlZCA8LSBjaGVja19jb3VudF9tYXRyaXgoY291bnRfZGF0YSA9IGN0c19hbGwsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sRGF0YSA9IGNvbGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2x1bW5fd2l0aF9jb2xfbmFtZXMgPSBzYW1wbGVfbmFtZXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICkKCiMgZmlsdGVyIGNvbERhdGEsIGFzIHN1Z2dlc3RlZCBieSBhYm92ZQpjb2xkYXRhIDwtIHN1YnNldF9jb2xEYXRhKGNvdW50X2RhdGEgPSBjdHNfYWxsLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbERhdGEgPSBjb2xkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1uX3dpdGhfY29sX25hbWVzID0gc2FtcGxlX25hbWVzKQoKI3JlLXJ1biBjaGVjawpjdHNfZmlsdGVyZWQgPC0gY2hlY2tfY291bnRfbWF0cml4KGNvdW50X2RhdGEgPSBjdHNfYWxsLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbERhdGEgPSBjb2xkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sdW1uX3dpdGhfY29sX25hbWVzID0gc2FtcGxlX25hbWVzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApCiNybShjdHNfYWxsKQpgYGAKCgoKIyAzLiBjb252ZXJ0IGVuc2VtYmxlIElEIHRvIGdlbmUgSUQKCmBgYHtyfQoKdGVzdF9hbm5vdCA8LSBhbm5vdGF0ZV9nZW5lX2Vuc2VtYmwoY3RzX2ZpbHRlcmVkLCBvcmdhbmlzbSA9ICJvYXJpZXMiKQpgYGAKCgojIFByZXBhcmUgZGF0YQpUTyBETzogbWFrZSBhIHdyYXBwZXIgZm9yIHRoaXMgd2l0aCBzcGVjaWZpYyBjaGVja3Mgb2YgZGF0YSAvIGF1dG8gbWF0cml4CmBgYHtyfQoKdGVzdF9kYXRhIDwtCiAgU3VtbWFyaXplZEV4cGVyaW1lbnQ6OlN1bW1hcml6ZWRFeHBlcmltZW50KAogICAgYXNzYXlzID0gY3RzX2ZpbHRlcmVkICU+JSAKICAgICAgdGliYmxlOjpjb2x1bW5fdG9fcm93bmFtZXModmFyID0gImdlbmVfZW5zZW1ibCIpICU+JSAKICAgICAgYXMubWF0cml4KCksCiAgICByb3dEYXRhID0gdGVzdF9hbm5vdCwgCiAgICBjb2xEYXRhID0gY29sZGF0YSkKCiNzdWJzZXQgY29sdW1ucyB0byBiZSBldmVyeSB0aGlyZCwgdG8gbWFrZSB0ZXN0aW5nIHF1aWNrZXIKdGVzdF9kYXRhIDwtIHRlc3RfZGF0YVssc2VxKDAsbmNvbChjdHNfZmlsdGVyZWQpLTEsNCldIAoKCmBgYAoKCgojNC4gR2VuZXJhdGUgREUgcmVzdWx0cwpUTyBETzogLSBkZXRlY3QgYWxsIG9wdGlvbnMgZm9yICd0b3BfbGV2ZWxfZmlsdGVyJyBhbmQgcGFyc2UgdG8gbWFwKCkuCgpgYGB7cn0KCkRFX291dCA8LSAKICBwdXJycjo6bWFwKC54ID0gbGlzdCgiTElWIiksCiAgICAgICAgICAgICAuZiA9IGF1dG9fZ2VuZXJhdGVfREVfcmVzdWx0cywgCiAgICAgICAgICAgICBzZV9kYXRhID0gdGVzdF9kYXRhLAogICAgICAgICAgICAgdG9wX2xldmVsX25hbWUgPSBSZWdpb24sCiAgICAgICAgICAgICBjb2x1bW5fb2Zfc2FtcGxlcyA9IHNhbXBsZV9uYW1lcywKICAgICAgICAgICAgIHNhbXBsZXNfdG9fcmVtb3ZlID0gTkEsCiAgICAgICAgICAgICBERVNlcTJfZm9ybXVsYV9kZXNpZ24gPSB+UmVnaW9uX0RpZXQsCiAgICAgICAgICAgICByb3dTdW1zX2ZpbHRlciA9IDEwLCAjZm9yIGRkcyBmaWx0ZXJpbmcKICAgICAgICAgICAgIHJlc3VsdHNfY29udHJhc3RfZmFjdG9yID0gUmVnaW9uX0RpZXQsCiAgICAgICAgICAgICByZXN1bHRzX2NvbWJpbmF0aW9ucyA9IE5BLAogICAgICAgICAgICAgdXNlX0lIV19maWx0ZXJpbmcgPSBUUlVFLAogICAgICAgICAgICAgYWxwaGEgPSAwLjA1LAogICAgICAgICAgICAgZ2VuZV9hbm5vdGF0aW9ucyA9IHRlc3RfYW5ub3QsCiAgICAgICAgICAgICBleHBvcnRfdGFibGVzID0gVFJVRSwKICAgICAgICAgICAgIGV4cG9ydF9kaXIgPSAiLi9vdXRwdXRzL25vcm1hbGlzZWRfY291bnRzMy8iKQoKCmBgYAoKIzUuIEFjY2Vzc2luZyByZXN1bHRzClRPIERPOiAKYGBge3J9CiN1bmxpc3QgdG8gdGFrZSBhd2F5IHRlaCB1bmFtZWQsIHRvcCBsYXllci4gR2l2ZXMgYWNjZXNzIHZpYSAkCkRFX291dF90ZXN0IDwtIERFX291dCAlPiUgdW5saXN0KHJlY3Vyc2l2ZSA9IEZBTFNFKQoKI3suW2dyZXBsKCJNQV9wbG90cyIsIG5hbWVzKC4pKV19CmBgYAoKIyMgQWNjZXNzaW5nIHNvcnRlZCBERSBUYWJsZXMgLSBwcmUtUElGCmBgYHtyfQpERV9vdXRfdGVzdCRMSVZfREVTZXEyX091dHB1dCRERVNlcTJfYW5ub3RfZGYKCmBgYAoKI1dvcmtpZ24KYGBge3J9CiN0ZXN0aW5nIGhvdyBtYW55IGhhdmUgcmVhbCBuYW1lcwogeCAlPiUgCiAgICAgICAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICAgICAgICB0aWJibGU6OnJvd25hbWVzX3RvX2NvbHVtbih2YXIgPSAiZ2VuZV9lbnNlbWJsIikgJT4lCiAgICAgICAgZHBseXI6OmxlZnRfam9pbihhbm5vdCwgYnkgPSBjKCJnZW5lX2Vuc2VtYmwiKSkgJT4lCiAgICAgICAgZHBseXI6OnNlbGVjdCguZGF0YSRnZW5lX2Vuc2VtYmwsCiAgICAgICAgICAgICAgICAgICAgICAuZGF0YSRnZW5lX25hbWUsCiAgICAgICAgICAgICAgICAgICAgICAuZGF0YSRkZXNjcmlwdGlvbiwKICAgICAgICAgICAgICAgICAgICAgIHRpZHlzZWxlY3Q6OmV2ZXJ5dGhpbmcoKSkgJT4lIAogICAgICAgIGFycmFuZ2UoLmRhdGEkcGFkaikKYGBgCgojIyBDb2RlIGZvciByZW5hbWluZyBvbGQgY3RzIHRhYmxlcwpgYGB7ciBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQojcmVhZCBpbiBjb3VudCB0YWJsZSAtIGh5cG90aGFsYW11cwoKY3RzX2h5cG9fbGl2IDwtIGRhdGEudGFibGU6OmZyZWFkKCIuLi9TaGVlcF9STkFzZXEvSW5wdXRzL2ZlYXR1cmVDb3VudHNfaHlwb3RoYWxhbXVzLWxpdmVyLnR4dCIsIGhlYWRlciA9IFQpCgpjb2xuYW1lcyhjdHNfaHlwb19saXYpWzFdIDwtICJnZW5lX2Vuc2VtYmwiCgojcmVuYW1lIGluY29ycmVjdCBlbnRyaWVzOgpjdHNfaHlwb19saXYgPC0gY3RzX2h5cG9fbGl2ICU+JSAKICBkcGx5cjo6cmVuYW1lKCJWTUhfMjFfSENQLUhQLVVNRUkiID0gIlZNSF8yMV9IQ1AtSFAtUk1FSSIsIAogICAgICAgICAgICAgICAgIlZNSF8wMl9IQ1AtTFAtVU1FSSIgPSAiVk1IXzAyX0xDUC1MUC1VTUVJIikKCgojcmVuYW1lIExBVCB0byBMSEEKY29sbmFtZXMoY3RzX2h5cG9fbGl2KSA8LSBzdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoc3RyaW5nID0gbmFtZXMoY3RzX2h5cG9fbGl2KSwgcGF0dGVybiA9ICJMQVQiLCByZXBsYWNlbWVudCA9ICJMSEEiKQoKI2ZpbmQgYWN0dWFsIHNhbXBsZSBuYW1lcyBmcm9tIHRhYmxlCnNlbGVjdGlvbiA8LSBtYXRjaChjb2xuYW1lcyhjdHNfaHlwb19saXYpWy0xXSwgY29sZGF0YVtbInJvd25hbWUiXV0gKSAlPiUgcHVycnI6OmRpc2NhcmQoaXMubmEpCgpuZXdfbmFtZXMgPC0gY29sZGF0YVtzZWxlY3Rpb24sXSRzYW1wbGVfbmFtZXMKY29sbmFtZXMoY3RzX2h5cG9fbGl2KVstMV0gPC0gbmV3X25hbWVzCgpzZWxlY3Rpb24gPC0gbWF0Y2goY29sbmFtZXMoY3RzX2h5cG9fbGl2KVstMV0sIGNvbGRhdGFbWyJyb3duYW1lIl1dICkgJT4lIHB1cnJyOjpkaXNjYXJkKGlzLm5hKQphbGwoKHRlbXAxW1sicm93bmFtZSJdXT09IGNvbG5hbWVzKGN0c19oeXBvX2xpdilbLTFdICkpCgoKI3JlYWQgaW4gY291bnQgdGFibGUgLSBHSVQgJiBTVApjdHNfZ2l0X3N0IDwtIGRhdGEudGFibGU6OmZyZWFkKCIuLi9TaGVlcF9STkFzZXEvSW5wdXRzL2ZlYXR1cmVDb3VudHNfbWF0cml4X0RVT19SVU1fU1RfMjAyMDA5MDEudGFidWxhciIpICU+JSAKICBkcGx5cjo6c2VsZWN0KCFjb250YWlucygiU1QiKSkKCmNvbG5hbWVzKGN0c19naXRfc3QpWzFdIDwtICJnZW5lX2Vuc2VtYmwiCgoKc2VsZWN0aW9uIDwtIG1hdGNoKGNvbG5hbWVzKGN0c19naXRfc3QpWy0xXSwgY29sZGF0YVtbInJvd25hbWUiXV0gKSAlPiUgcHVycnI6OmRpc2NhcmQoaXMubmEpCnRlbXAxIDwtIGNvbGRhdGFbc2VsZWN0aW9uLF0KYWxsKHRlbXAxW1sicm93bmFtZSJdXSA9PSBjb2xuYW1lcyhjdHNfZ2l0X3N0KVstMV0gKQoKbmV3X25hbWVzIDwtIHRlbXAxJHNhbXBsZV9uYW1lcwpjb2xuYW1lcyhjdHNfZ2l0X3N0KVstMV0gPC0gbmV3X25hbWVzCiNKb2luIGN0cyB0b2dldGhlcgoKY3RzX2FsbCA8LSBkcGx5cjo6ZnVsbF9qb2luKGN0c19oeXBvX2xpdiwgY3RzX2dpdF9zdCkKCmNvbG5hbWVzKGN0c19hbGwpCmBgYAoK